package Dane;

import Dane.Mp3Tree.Autor.Album;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import jmp3player.Jmp3PlayerView;

import static java.util.Collections.*;

/**
 *  Klasa reprezentuje drzewo biblioteki multimediów
 * @author lukeh
 * @version 2.0
 */
public class Mp3Tree
  {

    /**
     * Kolekcja wykonawców
     */
    public Vector<Autor> autor;

    /**
     * Konstruktor tworzy nową kolekcję Autorów
     */
    public Mp3Tree()
        {
        autor = new Vector<Autor>();
        }

    /**
     * Klasa zagnieżdżona reprezentująca wykonawcę utworu
     */
    public class Autor implements java.lang.Comparable
      {

        /**
         * Nazwa wykonawcy
         */
        public String name;
        /**
         * Kolekcja albumów wykonawcy
         */
        public Vector<Album> album;

        /**
         * Konstruktor tworzy kolekcję Albumów
         * Zapamiętuje nazwę Autora
         * @param n - nazwa autora
         */
        Autor(String n)
            {
            name = n;
            album = new Vector<Album>();

            }

        /**
         * Dodanie nowego albumu wykonawcy
         * @param f - plik mp3
         */
        public void addFile(Mp3File f)
            {

            for (Album a : album)
                {
                if (a.name.compareTo(f.Album) == 0)
                    {
                    a.addFile(f);
                    return;
                    }
                }
            Album a1 = new Album(f.Album);
            a1.addFile(f);
            album.add(a1);


            }

        /**
         * Metoda pozwalająca porównać dwa obiekty typu Autor
         * @param arg0 - obiekt do porównania
         * @return - wynik porównania
         */
        public int compareTo(Object arg0)
            {
            return name.compareTo(((Autor) arg0).name);
            }
    String getFile(Mp3File f)
    {
        System.out.println("szukam albumu");
        for(Album a: album)
        {
            if(a.name.compareTo(f.Album)==0) return a.getFile(f);
        }
        return null;
    }
        /**
         * Zagnieżdżona klasa reprezentująca album muzyczny
         */
        public class Album implements java.lang.Comparable
          {

            /**
             * Nazwa albumu
             */
            public String name;
            /**
             * Kolekcja utworów zawartych w albumie
             */
            public Vector<Mp3File> plik;

            /**
             * Konstruktor tworzy kolekcję Plików MP3
             * Zapamiętuje nazwę Albumu
             * @param n - nazwa Albumu
             */
            public Album(String n)
                {
                name = n;
                plik = new Vector<Mp3File>();
                }

            /**
             * Dodanie nowego utworu do albumu
             * @param f - plik mp3
             */
            public void addFile(Mp3File f)
                {
                for (Mp3File m : plik)
                    {
                    if (f.compareTo(m) == 0)
                        {
                        return;
                        }
                    }

                plik.add(f);

                }

            /**
             * Metoda pozwalająca porównać dwa obiekty typu Album
             * @param arg0 - obiekt do porównania
             * @return - wynik porównania
             */
            public int compareTo(Object arg0)
                {
                return name.compareTo(((Album) arg0).name);
                }
                String getFile(Mp3File f)
    {
        System.out.println("szukam pliku");
                            for(Mp3File p: plik)
        {
            if(p.Tytul.compareTo(f.Tytul)==0) return p.Adres;
        }
        return null;
    }
          }
      }

    /**
     * Dodanie nowego wykonawcy
     * Zabezpieczenie przed uruchomieniem w kilku wątkach
     * @param f - plik mp3
     */
    synchronized public void addFile(Mp3File f)
        {

        for (Autor a : autor)
            {
            if (a.name.compareTo(f.Autor) == 0)
                {

                a.addFile(f);
                return;
                }
            }

        Autor a1 = new Autor(f.Autor);
        a1.addFile(f);
        autor.add(a1);


        }

    /**
     * Zmiana klasy na XML
     * @return String reprezentujący kod XML
     */
    public String Mp3Tree2Xml()
        {
        XStream mapping = new XStream(new DomDriver());
        String xml = mapping.toXML(this);
        return xml;
        }

    /**
     * Generowanie drzewa biblioteki multimediów
     * @return uchwyt do korzenia
     */
    public DefaultMutableTreeNode genNode()
        {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        for (Autor aut : autor)
            {
            DefaultMutableTreeNode autNode = new DefaultMutableTreeNode(aut.name);
            for (Autor.Album alb : aut.album)
                {
                DefaultMutableTreeNode albNode = new DefaultMutableTreeNode(alb.name);
                for (Mp3File mp3 : alb.plik)
                    {
                    DefaultMutableTreeNode mp3Node = new DefaultMutableTreeNode(mp3.Tytul);
                    albNode.add(mp3Node);
                    }
                autNode.add(albNode);
                }
            root.add(autNode);
            }
        return root;
        }

    /**
     * Pobranie danych z pliku XML tree.xml i zbudowanie na jego podstawie drzewa
     * <u>Można poprawić w kolejnej wersji</u>
     */
    public void getTreeFile()
        {
        File settingsFile = new File("tree.xml");
        if (settingsFile == null)
            {
            try
                {
                settingsFile.createNewFile();
                } catch (IOException ex)
                {
                Logger.getLogger(Jmp3PlayerView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        Mp3Tree set = new Mp3Tree();
        FileInputStream fs;
        try
            {
            fs = new FileInputStream("tree.xml");
            DataInputStream ds = new DataInputStream(fs);

            String s = new String(), s1 = new String();
            int i = 0;
            while (true)
                {
                s1 = ds.readLine();
                if (s1 == null)
                    {
                    break;
                    }
                s += s1 + "\n";
                }
            set.xml2Mp3Tree(s);
            this.autor = set.autor;
            } catch (Exception ex)
            {
            Logger.getLogger(Jmp3PlayerView.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    /**
     * Zmiana XML na obiekt klasy
     * @param xml - treść dokumentu XML
     */
    public void xml2Mp3Tree(String xml)
        {
        XStream mapping = new XStream(new DomDriver());
        this.autor = ((Mp3Tree) mapping.fromXML(xml)).autor;

        }

    /**
     * Zapis Drzewa w postaći XML do pliku tree.xml
     */
    synchronized public void saveMp3TreeFile()
        {
        String s = Mp3Tree2Xml();
        FileOutputStream fs;
        try
            {
            fs = new FileOutputStream("tree.xml");
            DataOutputStream dos = new DataOutputStream(fs);
            try
                {
                dos.write(s.getBytes());
                } catch (IOException ex)
                {
                Logger.getLogger(Mp3Tree.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (FileNotFoundException ex)
            {
            Logger.getLogger(Mp3Tree.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    /**
     * Wyczyszczenie zawartości drzewa poprzez brutalne odcięcie korzenia
     */
    public void cleanTree()
        {
        autor = new Vector<Autor>();
        }

    /**
     * Sortowanie drzewa
     */
    public void sortTree()
        {
        sort(autor);

        for (Autor aut : autor)
            {
            sort(aut.album);
            for (Autor.Album alb : aut.album)
                {
                sort(alb.plik);
                }
            }
        }
    public String findFile(String au, String al, String ut)
    {
        if(au.length()==0 || al.length()==0 || ut.length()==0)
            return null;
        Mp3File f = new Mp3File();
        f.Album = al;
        f.Autor = au;
        f.Tytul = ut;
        try{
        return getFile(f);
        }
        catch(Exception e)
        {
            System.out.println("błąd!");
            return null;
        }
    }
    String getFile(Mp3File f)
    {
        System.out.println("szukam artusty" + f.Autor);
        for(Autor a: autor)
        {
            if(a.name.compareTo(f.Autor)==0) return a.getFile(f);
        }
        return null;
    }
  }
